/*******************************************************************************
 * Copyright (c) 2003 Boris Pruessmann and others. All rights reserved. This
 * program and the accompanying materials are made available under the terms of
 * the Common Public License v0.5 which accompanies this distribution, and is
 * available at http://www.eclipse.org/legal/cpl-v05.html
 * 
 * Contributors: Boris Pruessmann - Initial implementation.
 ******************************************************************************/
package net.sourceforge.perforce.ui.action;

import com.google.common.collect.Lists;

import net.sourceforge.perforce.core.api.ILogEntry;
import net.sourceforge.perforce.core.api.IPerforceServer;
import net.sourceforge.perforce.core.resources.IChangelist;
import net.sourceforge.perforce.core.resources.IP4File;
import net.sourceforge.perforce.core.resources.RemoteFile;
import net.sourceforge.perforce.core.resources.RemoteFolder;
import net.sourceforge.perforce.ui.internal.Policy;

import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.jface.viewers.IStructuredSelection;

import java.util.Iterator;
import java.util.List;

/**
 * @version $Revision: 488 $
 * @author <a href="mailto:bpruessmann@users.sourceforge.net">Boris
 *         Pruessmann</a>
 */
public final class SelectionHelper {
  // ------------------------------------------------------------------------
  // Private Constructors

  /** Constructor for SelectionHelper. */
  private SelectionHelper() {
  }

  // -----------------------------------------------------------------------
  // Public Static Methods

  /**
   * Returns the selected resources.
   * 
   * @param selection the selection from which the information will be obtained.
   * @return the selected resources
   * 
   * @pre selection != null
   * @post return != null
   */
  public static IResource[] getSelectedResources(IStructuredSelection selection) {
    // ==( PRE-CONDITION
    // )======================================================================
    Policy.assertNotNull(selection);
    // ==( PRE-CONDITION
    // )======================================================================

    List<IResource> resources = null;
    if (!selection.isEmpty()) {
      resources = Lists.newArrayList();
      for (Iterator<?> elements = selection.iterator(); elements.hasNext();) {
        Object next = elements.next();
        if (next instanceof IResource) {
          resources.add((IResource) next);
          continue;
        } else if (next instanceof IAdaptable) {
          IAdaptable a = (IAdaptable) next;
          Object adapter = a.getAdapter(IResource.class);
          if (adapter instanceof IResource) {
            resources.add((IResource) adapter);
            continue;
          }
        }
      }
    }

    if (resources != null && !resources.isEmpty()) {
      return resources.toArray(new IResource[resources.size()]);
    }

    return new IResource[0];
  }

  /**
   * Returns the selected remote files.
   * 
   * @param selection the selection from which the information will be obtained.
   * @return array of remote files.
   * 
   * @pre selection != null
   * @post return != null
   */
  public static RemoteFile[] getSelectedRemoteFiles(IStructuredSelection selection) {
    // ==( PRE-CONDITION
    // )======================================================================
    Policy.assertNotNull(selection);
    // ==( PRE-CONDITION
    // )======================================================================

    List<RemoteFile> resources = null;
    if (!selection.isEmpty()) {
      resources = Lists.newArrayList();
      for (Iterator<?> elements = selection.iterator(); elements.hasNext();) {
        Object next = elements.next();
        if (next instanceof RemoteFile) {
          resources.add((RemoteFile) next);
          continue;
        } else if (next instanceof IAdaptable) {
          IAdaptable a = (IAdaptable) next;
          Object adapter = a.getAdapter(RemoteFile.class);
          if (adapter instanceof RemoteFile) {
            resources.add((RemoteFile) adapter);
            continue;
          }
        }
      }
    }

    if (resources != null && !resources.isEmpty()) {
      return resources.toArray(new RemoteFile[resources.size()]);
    }

    return new RemoteFile[0];
  }

  /**
   * Call this method to retrieve the currently selected RemoteFolders.
   * 
   * @param selection the selection from which the information will be obtained.
   * @return the currently selected remote folders.
   * 
   * @pre selection != null
   * @post return != null
   */
  public static RemoteFolder[] getSelectedRemoteFolders(IStructuredSelection selection) {
    // ==( PRE-CONDITION
    // )======================================================================
    Policy.assertNotNull(selection);
    // ==( PRE-CONDITION
    // )======================================================================

    List<RemoteFolder> resources = null;
    if (!selection.isEmpty()) {
      resources = Lists.newArrayList();
      for (Iterator<?> elements = selection.iterator(); elements.hasNext();) {
        Object next = elements.next();
        if (next instanceof RemoteFolder) {
          resources.add((RemoteFolder) next);
          continue;
        } else if (next instanceof IAdaptable) {
          IAdaptable a = (IAdaptable) next;
          Object adapter = a.getAdapter(RemoteFolder.class);
          if (adapter instanceof RemoteFolder) {
            resources.add((RemoteFolder) adapter);
            continue;
          }
        }
      }
    }

    if (resources != null && !resources.isEmpty()) {
      return resources.toArray(new RemoteFolder[resources.size()]);
    }

    return new RemoteFolder[0];
  }

  /**
   * Called to retrieve an array of selected perforce files.
   * 
   * @param selection the selection from which the information will be obtained.
   * @return array of selected perforce files.
   * 
   * @pre selection != null
   * @post return != null
   */
  public static IP4File[] getSelectedPerforceFiles(IStructuredSelection selection) {
    // ==( PRE-CONDITION
    // )======================================================================
    Policy.assertNotNull(selection);
    // ==( PRE-CONDITION
    // )======================================================================

    List<IP4File> resources = null;
    if (!selection.isEmpty()) {
      resources = Lists.newArrayList();
      for (Iterator<?> elements = selection.iterator(); elements.hasNext();) {
        Object next = elements.next();
        if (next instanceof IP4File) {
          resources.add((IP4File) next);
          continue;
        } else if (next instanceof IAdaptable) {
          IAdaptable a = (IAdaptable) next;
          Object adapter = a.getAdapter(IP4File.class);
          if (adapter instanceof IP4File) {
            resources.add((IP4File) adapter);
            continue;
          }
        }
      }
    }

    if (resources != null && !resources.isEmpty()) {
      return resources.toArray(new IP4File[resources.size()]);
    }

    return new IP4File[0];
  }

  /**
   * Called to retrieve an array of selected changelists.
   * 
   * @param selection the selection from which the information will be obtained.
   * @return array of selected changelists.
   * 
   * @pre selection != null
   * @post return != null
   */
  public static IChangelist[] getSelectedChangelists(IStructuredSelection selection) {
    // ==( PRE-CONDITION
    // )======================================================================
    Policy.assertNotNull(selection);
    // ==( PRE-CONDITION
    // )======================================================================

    List<IChangelist> resources = null;
    if (!selection.isEmpty()) {
      resources = Lists.newArrayList();
      for (Iterator<?> elements = selection.iterator(); elements.hasNext();) {
        Object next = elements.next();
        if (next instanceof IChangelist) {
          resources.add((IChangelist) next);
          continue;
        } else if (next instanceof IAdaptable) {
          IAdaptable a = (IAdaptable) next;
          Object adapter = a.getAdapter(IChangelist.class);
          if (adapter instanceof IChangelist) {
            resources.add((IChangelist) adapter);
            continue;
          }
        }
      }
    }

    if (resources != null && !resources.isEmpty()) {
      return resources.toArray(new IChangelist[resources.size()]);
    }

    return new IChangelist[0];
  }

  /**
   * Call this method to retrieve an array of selected servers.
   * 
   * @param selection the selection from which the information will be obtained.
   * @return array of selected servers.
   * 
   * @pre selection != null
   * @post return != null
   */
  public static IPerforceServer[] getSelectedServers(IStructuredSelection selection) {
    // ==( PRE-CONDITION
    // )======================================================================
    Policy.assertNotNull(selection);
    // ==( PRE-CONDITION
    // )======================================================================

    List<IPerforceServer> resources = null;
    if (!selection.isEmpty()) {
      resources = Lists.newArrayList();
      for (Iterator<?> elements = selection.iterator(); elements.hasNext();) {
        Object next = elements.next();
        if (next instanceof IPerforceServer) {
          resources.add((IPerforceServer) next);
          continue;
        } else if (next instanceof IAdaptable) {
          IAdaptable a = (IAdaptable) next;
          Object adapter = a.getAdapter(IPerforceServer.class);
          if (adapter instanceof IPerforceServer) {
            resources.add((IPerforceServer) adapter);
            continue;
          }
        }
      }
    }

    if (resources != null && !resources.isEmpty()) {
      return resources.toArray(new IPerforceServer[resources.size()]);
    }

    return new IPerforceServer[0];
  }

  /**
   * Call this method to retrieve an array of selected log entries.
   * 
   * @param selection the selection from which the information will be obtained.
   * @return array of selected servers.
   * 
   * @pre selection != null
   * @post return != null
   */
  public static ILogEntry[] getSelectedLogEntries(IStructuredSelection selection) {
    // ==( PRE-CONDITION
    // )======================================================================
    Policy.assertNotNull(selection);
    // ==( PRE-CONDITION
    // )======================================================================

    List<ILogEntry> resources = null;
    if (!selection.isEmpty()) {
      resources = Lists.newArrayList();
      for (Iterator<?> elements = selection.iterator(); elements.hasNext();) {
        Object next = elements.next();
        if (next instanceof ILogEntry) {
          resources.add((ILogEntry) next);
          continue;
        } else if (next instanceof IAdaptable) {
          IAdaptable a = (IAdaptable) next;
          Object adapter = a.getAdapter(ILogEntry.class);
          if (adapter instanceof ILogEntry) {
            resources.add((ILogEntry) adapter);
            continue;
          }
        }
      }
    }

    if (resources != null && !resources.isEmpty()) {
      return resources.toArray(new ILogEntry[resources.size()]);
    }

    return new ILogEntry[0];
  }
}
